home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1998 May
/
EnigmA AMIGA RUN 27 (1998)(G.R. Edizioni)(IT)[!][issue 1998-05].iso
/
earcd
/
sinclair-ql
/
pdtk_asm
< prev
next >
Wrap
Text File
|
1998-02-11
|
29KB
|
1,848 lines
SECTION PDTK
DATA 0
NOLIST
INCLUDE 'QDOS_inc'
LIST
; --------------------------------------------------------------
; PDTK_asm - Freeware toolkit
; - last modified 08/09/95
; ... by Mark J Swift - All rights reserved.
; to assemble with the GST/QUANTA assembler use the command line:
; PDTK_asm -nolink -nolist -bin PDTK_rext
; to assemble with HISOFT DEVPAC remove the SECTION directive,
; and change the line "bra.l TK_START" to "bra TK_START"
; set TABS to EIGHT characters before editing this file
; --------------------------------------------------------------
BASE:
; *** Comment out ONE of the following two lines to ***
; *** create either a ROM or a BASIC toolkit. ***
bra.l TK_START ; ...If I'm a BASIC toolkit!
; dc.l $4AFB0001 ; ...If I'm a ROM!
dc.w PROC_DEF-BASE
dc.w ROM_START-BASE
BANNER:
dc.b 0,72,'PDTK Freeware BASIC toolkit v1.12',$A
dc.b '1995 M J Swift - All rights reserved',$A
; --------------------------------------------------------------
; start of ROM code
; --------------------------------------------------------------
TK_START:
movem.l d1-d3/a0-a3,-(a7)
lea PROC_DEF(pc),a1
move.w BP.INIT,a2
jsr (a2)
lea BANNER(pc),a1 ; start of message
suba.l a0,a0 ; output channel 0
move.w UT.MTEXT,a2
jsr (a2) ; print it
bra.s TK_DOIT
ROM_START:
movem.l d1-d3/a0-a3,-(a7)
TK_DOIT:
bsr TKILL
moveq #ERR.OK,d0
movem.l (a7)+,d1-d3/a0-a3
rts
; -------------------------------------------------------------
PROC_DEF:
dc.w 11
dc.w PDTK_EXT-*
dc.b 8,'PDTK_EXT',0
dc.w EXTRAS-*
dc.b 6,'EXTRAS',0
dc.w TOOLKILL-*
dc.b 8,'TOOLKILL',0
dc.w P_TRACE-*
dc.b 7,'P_TRACE'
dc.w J_TRACE-*
dc.b 7,'J_TRACE'
dc.w J_TRACE_W-*
dc.b 9,'J_TRACE_W'
; dc.w MC_TRACE-*
; dc.b 8,'MC_TRACE',0
dc.w 0
dc.w 4
dc.w PDTK_VER-*
dc.b 9,'PDTK_VER$'
dc.w WHERE-*
dc.b 5,'WHERE'
dc.w F_TRACE-*
dc.b 7,'F_TRACE'
dc.w 0
; -------------------------------------------------------------
PDTK_EXT:
lea PDTK_DEF(pc),a1
move.w $110,a2
jsr (a2)
bra.s TKILL
; -------------------------------------------------------------
EXTRAS:
moveq #1,d1
bsr FETCH_CH
bne.s EXTRASX
cmp.l a3,a5
bne RPORT.BP
move.l a0,a4 ; channel ID
move.l BV_NTBAS(a6),a3
move.l BV_NTP(a6),a5
EX_TYPE:
move.w 0(a6,a3.l),d3
beq.s EX_SKIP
cmp.w #$0800,d3
beq.s EX_CONT
cmp.w #$0900,d3
bne.s EX_SKIP
EX_CONT:
cmp.l #$C000,4(a6,a3.l)
blt.s EX_SKIP
move.l BV_NLBAS(a6),a1
adda.w 2(a6,a3.l),a1
move.b 0(a6,a1.l),d2
ext.w d2 ; length of string
beq.s EX_SKIP
addq.l #1,a1 ; address of string
move.l a4,a0 ; channel ID
moveq #-1,d3
trap #4 ; relative to a6
moveq #IO.SSTRG,d0
trap #3 ; print string
tst.l d0
bne.s EXTRASX
moveq #$0A,d1 ; linefeed
moveq #-1,d3
moveq #IO.SBYTE,d0
trap #3
tst.l d0
bne.s EXTRASX
EX_SKIP:
addq.l #8,a3
cmp.l a3,a5
bne EX_TYPE
moveq #0,d0
EXTRASX:
rts
; -------------------------------------------------------------
TOOLKILL:
cmp.l a3,a5
bne RPORT.BP
TKILL:
move.l BV_NTBAS(a6),a2
move.l BV_NTP(a6),a5
bra TK_TYPNXT
TK_TYPLUP:
move.w 0(a6,a5.l),d3
beq TK_TYPNXT
cmp.w #$0900,d3
beq.s TK_CONT
cmp.w #$0800,d3
bne TK_TYPNXT
TK_CONT:
move.l a5,a3
bra TK_FNPRC
TK_DUPLUP:
move.w 0(a6,a3.l),d4
beq TK_DUPNXT
cmp.w #$0800,d4
beq.s TK_NPTR
cmp.w #$0900,d4
beq.s TK_NPTR
cmp.w #$0303,d4
bgt.s TK_DUPNXT
TK_NPTR:
move.l BV_NLBAS(a6),a1
move.l a1,a0
adda.w 2(a6,a4.l),a1 ; name list entry
adda.w 2(a6,a3.l),a0
move.b 0(a6,a1.l),d1 ; length of name
cmp.b 0(a6,a0.l),d1
bne.s TK_DUPNXT
ext.w d1
beq.s TK_DUPNXT
subq.w #1,d1
TK_NAMLUP:
addq.l #1,a1
addq.l #1,a0
move.b 0(a6,a0.l),d0
move.b 0(a6,a1.l),d2
eor.b d2,d0
andi.b #223,d0 ; compare name
bne.s TK_DUPNXT
dbra d1,TK_NAMLUP
cmp.w #$0303,d4
ble.s TK_TYP3
cmp.b #'$',d2
bne.s TK_TYP1
move.w #$0001,d4 ; set to unset $ var
bra.s TK_TYP3
TK_TYP1:
cmp.b #'%',d2
bne.s TK_TYP2
move.w #$0003,d4 ; set to unset % var
bra.s TK_TYP3
TK_TYP2:
move.w #$0002,d4 ; set to unset FP var
TK_TYP3:
move.w 0(a6,a4.l),0(a6,a3.l) ; copy old to new
move.w d4,0(a6,a4.l) ; & set old type
; move.w 2(a6,a3.l),d0
; move.w 2(a6,a4.l),2(a6,a3.l)
; move.w d0,2(a6,a4.l) ; swap name pointer
;
move.l 4(a6,a3.l),d0
move.l 4(a6,a4.l),4(a6,a3.l)
move.l d0,4(a6,a4.l) ; swap 'value'
TK_FNPRC:
move.l a3,a4 ; new fn/proc
TK_DUPNXT:
subq.l #8,a3
cmp.l a3,a2
ble TK_DUPLUP
TK_TYPNXT:
subq.l #8,a5
cmp.l a5,a2
ble TK_TYPLUP
TK_EXIT:
moveq #0,d0
rts
; -------------------------------------------------------------
PDTK_VER:
cmp.l a3,a5
bne RPORT.BP
move.l #'1.12',d1
bra RET_4S
; -------------------------------------------------------------
J_TRACE:
moveq #0,d5
bra J_TRC1
J_TRACE_W:
moveq #-1,d5
J_TRC1:
moveq #1,d7 ; old shared device
bsr FL_ID
bne FEXIT
move.l a4,d4 ; channel ID to close
bsr HEDR1 ; read file header
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
moveq #MT.CJOB,d0 ; create job in trns prog
moveq #-1,d1 ; owner of job
move.l 0(a2),d2 ; length
move.l 6(a2),d3 ; dataspace
suba.l a1,a1 ; start address
trap #1
movea.l a0,a4 ; allocated start
tst.l d0
bne SDONE1
move.l d1,d6 ; save Job ID
move.l d4,a0 ; File ID
move.l a4,a1 ; location to load
moveq #-1,d3 ; infinite timeout
moveq #FS.LOAD,d0
trap #3 ; load file
bsr SDONE1
tst.l d0
bne J_TRCR
ori.w #$8000,-JB_END+JB_SR(a4) ; trace on
moveq #MT.ACTIV,d0 ; activate the job
move.l d6,d1 ; restore Job ID
moveq #$20,d2 ; priority
move.l d5,d3 ; timeout
trap #1
tst.l d0
bne.s J_TRCR
tst.l d5
bne.s J_TRCX
moveq #MT.SUSJB,d0 ; suspend a job
moveq #-1,d1 ; me (usually BASIC)
moveq #$19,d3 ; timeout
suba.l a1,a1 ; no flag
trap #1
J_TRCX:
rts
J_TRCR:
move.l d0,d7 ; save error code
moveq #MT.RJOB,d0 ; remove job
move.l d6,d1 ; restore Job ID
trap #1
move.l d7,d0 ; restore error code
rts
; -------------------------------------------------------------
F_TRACE:
bsr FETCH_S
bne.s TRACEX
bsr.s WHEREIS ; find address of FN/PROC
cmpi.w #$0900,d0
beq.s TRACEON
bra RPORT.BP
; -------------------------------------------------------------
P_TRACE:
bsr FETCH_S
bne.s TRACEX
bsr.s WHEREIS ; find address of FN/PROC
cmpi.w #$0800,d0
bne RPORT.BP
; -------------------------------------------------------------
TRACEON:
trap #0 ; enter supervisor mode
ori.w #$8000,sr ; trace on
andi.w #$DFFF,sr ; enter user mode
jsr (a0) ; do FN/PROC
TRACEOFF:
trap #0 ; enter supervisor mode
andi.w #$1FFF,sr ; clear trace, exit supervisor
TRACEX:
rts
; -------------------------------------------------------------
;MC_TRACE:
; bsr FETCH_W
; bne.s MC_TXIT
; tst.w d1
; beq.s MC_TOFF
; trap #0
; ori.w #$8000,sr
; andi.w #$DFFF,sr
; rts
;MC_TOFF:
; trap #0
; andi.w #$1FFF,sr
;MC_TXIT:
; rts
; -------------------------------------------------------------
WHERE:
bsr FETCH_S
bne.s WHEREX
cmp.l a3,a5
bne RPORT.NO
bsr.s WHEREIS
move.l a0,d1
bra RET_L
WHEREX:
; -------------------------------------------------------------
; Enter: A1=pointer to fn/proc NAME (string) on math stack
; Exit: A1=updated pointer
; D0=NAME type (i.e. proc=$0800, fn=$0900)
; A0=address of fn/proc
WHEREIS:
movem.l d1-d2/a2-a5,-(a7)
move.w 0(a6,a1.l),d0
beq.s WHER_FAIL
cmp.w #256,d0
bcc.s WHER_FAIL
addq.l #1,a1
move.l a1,a3
move.l BV_NTBAS(a6),a4
move.l BV_NTP(a6),a5
WHER_LUP1:
move.l BV_NLBAS(a6),a2
add.w 2(a6,a4.l),a2
move.b 0(a6,a1.l),d0
cmp.b 0(a6,a2.l),d0
bne.s WHER_NXT
ext.w d0
subq.w #1,d0
WHER_LUP2:
addq.l #1,a1
addq.l #1,a2
move.b 0(a6,a1.l),d1
move.b 0(a6,a2.l),d2
eor.b d2,d1
andi.b #$DF,d1
bne.s WHER_NXT
dbra d0,WHER_LUP2
move.w 0(a6,a4.l),d0 ; type
move.l 4(a6,a4.l),a0 ; address
bra.s WHER_RTS
WHER_NXT:
move.l a3,a1
addq.l #8,a4
cmp.l a5,a4
bne WHER_LUP1
WHER_FAIL:
moveq #0,d0
move.l d0,a0
WHER_RTS:
move.l a3,a1
subq.l #1,a1
moveq #3,d1 ; get total length of string
add.w 0(a6,a1.l),d1
bclr #0,d1
add.l d1,a1 ; and update a1
movem.l (a7)+,d1-d2/a2-a5
rts
; -------------------------------------------------------------
PDTK_DEF:
dc.w 15
dc.w RESET-*
dc.b 5,'RESET'
dc.w RECHP-*
dc.b 5,'RECHP'
dc.w CLCHP-*
dc.b 5,'CLCHP'
dc.w LRESPR-*
dc.b 6,'LRESPR',0
dc.w DDLIST-*
dc.b 6,'DDLIST',0
dc.w SACS-*
dc.b 9,'SET_FACCS'
dc.w STYP-*
dc.b 8,'SET_FTYP',0
dc.w SDAT-*
dc.b 8,'SET_FDAT',0
dc.w SXTRA-*
dc.b 9,'SET_FXTRA'
dc.w CURSEN-*
dc.b 6,'CURSEN',0
dc.w CURDIS-*
dc.b 6,'CURDIS',0
dc.w 0
dc.w 23
dc.w QDOS-*
dc.b 5,'QDOS$'
dc.w SYSBASE-*
dc.b 7,'SYSBASE'
dc.w ALCHP-*
dc.b 5,'ALCHP'
dc.w FREE_MEM-*
dc.b 8,'FREE_MEM',0
dc.w FLEN-*
dc.b 4,'FLEN',0
dc.w FACS-*
dc.b 5,'FACCS'
dc.w FTYP-*
dc.b 4,'FTYP',0
dc.w FDAT-*
dc.b 4,'FDAT',0
dc.w FXTRA-*
dc.b 5,'FXTRA'
dc.w FTEST-*
dc.b 5,'FTEST'
dc.w DDTEST-*
dc.b 6,'DDTEST',0
dc.w HEXS-*
dc.b 4,'HEX$',0
dc.w HEX-*
dc.b 3,'HEX'
dc.w INTEGERS-*
dc.b 8,'INTEGER$',0
dc.w LONGINTS-*
dc.b 8,'LONGINT$',0
dc.w FLOATS-*
dc.b 6,'FLOAT$',0
dc.w STRINGS-*
dc.b 7,'STRING$'
dc.w STRINGI-*
dc.b 7,'STRING%'
dc.w STRINGL-*
dc.b 7,'STRINGL'
dc.w STRINGF-*
dc.b 7,'STRINGF'
dc.w 0
; -------------------------------------------------------------
QDOS:
cmp.l a3,a5
bne RPORT.BP
moveq #MT.INF,d0
trap #1
move.l d2,d1
bra RET_4S
; -------------------------------------------------------------
SYSBASE:
cmp.l a3,a5
bne RPORT.BP
moveq #MT.INF,d0
trap #1
move.l a0,d1
bra RET_L
; -------------------------------------------------------------
RESET:
cmp.l a3,a5
bne RPORT.BP
trap #0
ori.w #$0700,sr
move.l $0,a7 ; reset supervisor stack
move.l a7,d0
andi.l #$FFFF8000,d0
move.l d0,a6
suba.l a0,a0
tst.b 161(a6) ; skip if not 010+
beq.s RESET2
dc.w $4E7A,$8801 ; movec vbr,a0
RESET2:
move.l $4(a0),-(a7) ; jump to reset routine
rts
; -------------------------------------------------------------
RECHP:
bsr FETCH_L
bne.s RECHX
cmp.l a3,a5
bne RPORT.BP
subq.l #4,d1 ; compensate for link
lea $E0(a6),a1 ; BASICs list of allocations
RECHL:
move.l (a1),d0
beq RPORT.OR ; indicate error if no link
move.l d0,a1
cmp.l d0,d1 ; look for allocation in list
bne.s RECHL
move.l d1,a0 ; address of link
lea $E0(a6),a1 ; BASICs list of allocations
move.w UT.UNLNK,a4
jsr (a4) ; remove from linked list
moveq #MT.RECHP,d0
trap #1 ; release memory
RECHX:
rts
; -------------------------------------------------------------
CLCHP:
cmp.l a3,a5
bne RPORT.BP
lea $E0(a6),a1 ; BASICs list of allocations
move.l (a1),d0
beq.s CLCHPX
clr.l (a1)
CLCHPL:
move.l d0,a4
move.l d0,a0
moveq #MT.RECHP,d0
trap #1
move.l (a4),d0
bne.s CLCHPL
CLCHPX:
rts
; -------------------------------------------------------------
; ALCHP(HP.REQ)
; or ALCHP(JB.ID,HP.REQ)
; or ALCHP(JB.NUM,JB.TAG,HP.REQ)
ALCHP:
move.l a5,d5
sub.l a3,d5
beq RPORT.BP
moveq #-1,d2 ; default job ID
cmp.w #1*8,d5 ; one parameter?
beq.s ALCH1P
cmp.w #3*8,d5
bgt RPORT.BP
move.l a5,-(a7)
lea -8(a5),a5
bsr FETCH_ID ; get job ID
movea.l a5,a3
movea.l (a7)+,a5
bne.s ALCHX
move.l d1,d2 ; in d2!
ALCH1P:
bsr FETCH_L
bne.s ALCHX
tst.l d1
ble RPORT.OR ; shouldn't allocate nought
addq.l #4,d1 ; room for link
moveq #MT.ALCHP,d0
trap #1
tst.l d0
bne.s ALCHX
lea $E0(a6),a1 ; BASICs list of allocations
move.w UT.LINK,a4
jsr (a4) ; add to linked list
move.l a0,d1 ; address of allocation
addq.l #4,d1 ; skip over link
bra RET_L
ALCHX:
rts
; -------------------------------------------------------------
FREE_MEM:
moveq #MT.INF,d0
trap #1
move.l SV_BASIC(a0),d1
sub.l SV_FREE(a0),d1
subi.l #$400,d1 ; a bit of lea-way
bra RET_L
; -------------------------------------------------------------
LRESPR:
moveq #1,d7 ; old shared device
bsr FL_ID
bne FEXIT
move.l a4,d4 ; channel ID to close
bsr HEDR1 ; read file header
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
move.l 0(a2),d1 ; get length of file
movem.l d1/a2,-(a7) ; save len & header buffer
moveq #MT.ALRES,d0
trap #1 ; allocate space
move.l a0,a1 ; location
movem.l (a7)+,d2/a2 ; restore len & header buffer
tst.l d0
bne SDONE1 ; no room so quit
move.l a1,-(a7) ; stack return address
move.l a4,a0 ; File ID
moveq #-1,d3 ; infinite timeout
moveq #FS.LOAD,d0
trap #3 ; load file
tst.l d0
beq SDONE1 ; no errors.
addq.l #4,a7 ; failed to load
bra SDONE1
; -------------------------------------------------------------
FLEN:
moveq #1,d7 ; old shared device
bsr FGEN
bne SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
move.l 0(a2),d6
bra.s FDONE
; -------------------------------------------------------------
FACS:
moveq #1,d7 ; old shared device
bsr FGEN
bne SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
move.b 4(a2),d6
ext.w d6
ext.l d6
bra.s FDONE
; -------------------------------------------------------------
FTYP:
moveq #1,d7 ; old shared device
bsr FGEN
bne SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
move.b 5(a2),d6
ext.w d6
ext.l d6
bra.s FDONE
; -------------------------------------------------------------
FDAT:
moveq #1,d7 ; old shared device
bsr FGEN
bne SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne SDONE1
move.l 6(a2),d6
bra.s FDONE
; -------------------------------------------------------------
FXTRA:
moveq #1,d7 ; old shared device
bsr FGEN
bne SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne.s SDONE1
move.l $A(a2),d6
; -------------------------------------------------------------
FDONE:
moveq #ERR.OK,d0 ; no errors
bsr.s SDONE1
FDONE1:
move.l d6,d1
bra RET_L
; -------------------------------------------------------------
FEXIT:
rts
; -------------------------------------------------------------
SACS:
moveq #0,d7 ; old exclusive device
bsr FGEN
bne.s SDONE1
bsr FETCH_W
bne.s SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne.s SDONE1
move.b d1,4(a2)
bra.s SDONE
; -------------------------------------------------------------
STYP:
moveq #0,d7 ; old exclusive device
bsr.s FGEN
bne.s SDONE1
bsr FETCH_W
bne.s SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne.s SDONE1
move.b d1,5(a2)
bra.s SDONE
; -------------------------------------------------------------
SDAT:
moveq #0,d7 ; old exclusive device
bsr.s FGEN
bne.s SDONE1
bsr FETCH_L
bne.s SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne.s SDONE1
move.l d1,6(a2)
bra.s SDONE
; -------------------------------------------------------------
SXTRA:
moveq #0,d7 ; old exclusive device
bsr.s FGEN
bne.s SDONE1
bsr FETCH_L
bne.s SDONE1
moveq #ERR.BP,d0
cmp.l a3,a5
bne.s SDONE1
move.l d1,$A(a2)
; -------------------------------------------------------------
SDONE:
moveq #ERR.OK,d0 ; no errors
move.l a4,a0 ; channel ID
move.l a2,a1 ; location of header
moveq #14,d2
moveq #-1,d3
moveq #FS.HEADS,d0 ; set header
trap #3
SDONE1:
move.l d0,d7 ; save error code
move.l a2,d0
beq.s SDONE2
move.l a2,a0
moveq #MT.RECHP,d0
trap #1 ; release buffer
SDONE2:
tst.l d4
beq.s SEXIT
move.l d4,a0
moveq #IO.CLOSE,d0 ; close file
trap #2
SEXIT:
move.l d7,d0 ; restore error code
rts
; -------------------------------------------------------------
FGEN:
moveq #0,d4 ; no channel to close yet
bsr BKSLSH
beq.s FGEN1
moveq #1,d1 ; default channel
bsr FETCH_CH
bne.s FGENX
move.l a0,a4 ; store channel ID
bra.s FGEN3
FGEN1:
bsr FETCH_N
bne.s FGENX
FGEN2:
bsr.s FL_ID
bne.s FGENX
move.l a4,d4 ; channel ID to close
FGEN3:
bsr.s HEDR1 ; read file header
FGENX:
rts
; -------------------------------------------------------------
FL_ID:
bsr GET1_FNAMES
bne.s FL_IDX
FL_ID1:
moveq #0,d1
move.w 0(a6,a1.l),d1 ; length of filename
move.l a1,a0 ; address of filename
move.l d7,d3 ; shared or exclusive...
moveq #-1,d1 ; current job
trap #4 ; relative to a6
moveq #IO.OPEN,d0 ; try to open file
trap #2
tst.l d0
bne.s FL_IDX ; error
move.l a0,a4 ; store channel ID
FL_IDX:
rts
; -------------------------------------------------------------
HEDR1:
movem.l d2-d3/d7/a1/a3,-(a7)
moveq #64,d1 ; space required
moveq #-1,d2 ; owner job = me
moveq #MT.ALCHP,d0
trap #1
tst.l d0
bne.s HEDRX
move.l a0,a2 ; address of buffer
move.l a4,a0 ; channel ID
move.l a2,a1 ; location for header
moveq #64,d2
moveq #-1,d3
moveq #FS.HEADR,d0 ; get 64 bytes of header
trap #3
tst.l d0
beq.s HEDRX ; no errors... exit
move.l d0,d7 ; save error code
move.l a2,a0
moveq #MT.RECHP,d0
trap #1 ; release buffer
suba.l a2,a2 ; indicate no buffer
move.l d7,d0 ; restore error
HEDRX:
movem.l (a7)+,d2-d3/d7/a1/a3
rts
; -------------------------------------------------------------
FTEST:
bsr GET1_FNAMES
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #0,d1
move.w 0(a6,a1.l),d1 ; length of filename
move.l a1,a0 ; address of filename
moveq #0,d3 ; old exclusive device
moveq #-1,d1 ; current job
trap #4 ; relative to a6
moveq #IO.OPEN,d0 ; try to open file
trap #2
move.l d0,d6
bne.s FTEST1
moveq #IO.CLOSE,d0 ; close file
trap #2
FTEST1:
move.l d6,d1
bra RET_L
; -------------------------------------------------------------
DDTEST:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #MT.INF,d0
trap #1
move.l SV_DDLST(a0),a0
bra.s DDTST1
DDTSTL:
move.l (a0),a0
DDTST1:
move.l a0,d0
beq.s DDTST.NF ; device not in list
lea $24(a0),a4 ; address of name
move.l a1,a2
move.w (a4)+,d0
cmp.w 0(a6,a2.l),d0
bne.s DDTSTL
addq.l #2,a2
bra.s DDTST2
DDTSTL2:
move.b (a4)+,d1
move.b 0(a6,a2.l),d2
eor.b d2,d1
andi.b #$DF,d1
bne.s DDTSTL
addq.l #1,a2
DDTST2:
dbra d0,DDTSTL2
moveq #ERR.OK,d1
bra.s DDTSTX
DDTST.NF:
moveq #ERR.NF,d1
DDTSTX:
bra RET_L
; -------------------------------------------------------------
DDLIST:
moveq #1,d1
bsr FETCH_CH
bne.s DDLISTX
cmp.l a3,a5
bne RPORT.BP
move.l a0,a3 ; save channel id
moveq #MT.INF,d0
trap #1 ; get address of sys vars in a0
move.l SV_DDLST(a0),a4 ; address of first device driver
move.l a3,a0 ; restore channel id
DDLISTL:
lea $24(a4),a1
bsr IOSTRG
bne.s DDLISTX
moveq #$0A,d1 ; linefeed
moveq #-1,d3
moveq #IO.SBYTE,d0
trap #3
tst.l d0
bne.s DDLISTX
move.l (a4),a4
move.l a4,d0
tst.l d0
bne.s DDLISTL
DDLISTX:
rts
; -------------------------------------------------------------
HEXS:
bsr FETCH_L
bne.s HEXSX
move.l d1,d2
bsr FETCH_W
bne.s HEXSX
cmp.l a3,a5
bne RPORT.BP
cmp.w #32,d1
bgt RPORT.OR
addq.w #3,d1
lsr.w #2,d1 ; number of digits
beq RPORT.OR
move.l BV_RIP(a6),a1
btst #0,d1
beq.s HEXS1
subq.l #1,a1
HEXS1:
move.w d1,d3
subq.w #1,d3
HEXSL:
move.l d2,d0
andi.b #15,d0
cmpi.b #10,d0
blt.s HEXS2
addq.b #7,d0
HEXS2:
addi.b #48,d0
subq.l #1,a1
move.b d0,0(a6,a1.l)
lsr.l #4,d2
dbra d3,HEXSL
subq.l #2,a1
move.w d1,0(a6,a1.l)
move.l a1,BV_RIP(a6)
moveq #1,d4
moveq #ERR.OK,d0
HEXSX:
rts
; -------------------------------------------------------------
HEX:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
move.w 0(a6,a1.l),d1
beq RPORT.BP
cmp.w #8,d1
bgt RPORT.BP
addq.l #2,a1
subq.w #1,d1
moveq #0,d2
HEXL:
move.b 0(a6,a1.l),d0
addq.l #1,a1
subi.b #48,d0
bmi RPORT.OR
cmpi.b #10,d0
blt.s HEX1
andi.b #223,d0
cmpi.b #17,d0
blt RPORT.OR
subq.b #7,d0
cmpi.b #15,d0
bgt RPORT.OR
HEX1:
lsl.l #4,d2
or.b d0,d2
dbra d1,HEXL
move.l d2,d1
bra RET_L
; -------------------------------------------------------------
STRINGL:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
move.w 0(a6,a1.l),d1
cmp.w #4,d1
bne RPORT.BP
move.l 2(a6,a1.l),d1
bra RET_L
; -------------------------------------------------------------
STRINGI:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #2,d2
moveq #3,d4
bra.s NUMFORM
; -------------------------------------------------------------
STRINGF:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #6,d2
moveq #2,d4
NUMFORM:
move.w 0(a6,a1.l),d1
cmp.w d2,d1
bne RPORT.BP
addq.l #2,a1
move.l a1,BV_RIP(a6)
rts
; -------------------------------------------------------------
INTEGERS:
bsr FETCH_W
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #2,d4
bra.s STRFORM
; -------------------------------------------------------------
LONGINTS:
move.w CA.GTLIN,a2
bsr GET_ONE
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #4,d4
bra.s STRFORM
; -------------------------------------------------------------
FLOATS:
bsr FETCH_F
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
moveq #6,d4
bra.s STRFORM
; -------------------------------------------------------------
STRINGS:
bsr FETCH_S
bne RPORT.BP
cmp.l a3,a5
bne RPORT.BP
move.w 0(a6,a1.l),d4
addq.w #2,d4
STRFORM:
; moveq.l #2,d1
; move.w BV.CHRIX,a2
; jsr (a2)
subq.l #2,a1 ; 2 bytes for string len
move.l a1,BV_RIP(a6)
move.w d4,0(a6,a1.l)
moveq #1,d4
moveq #0,d0
rts
; -------------------------------------------------------------
CURSEN:
moveq #SD.CURE,d5
bra.s CURSR
CURDIS:
moveq #SD.CURS,d5
CURSR:
moveq #1,d1
bsr FETCH_CH
bne.s CURSR_X
cmp.l a3,a5
bne RPORT.BP
move.w #-1,d3
move.b d5,d0
trap #3
CURSR_X:
rts
; -------------------------------------------------------------
; Entry: A3.L pointer to first parameter
; A5.L pointer to last parameter
;
; Exit: A3.L updated
; A5.L updated
; A1.L pointer to result
; D0.L...error code
; D1.W result (or mantissa or string length)
; Fetch one null parameter
FETCH_N:
move.b 1(a6,a1.l),d0
andi.w #$0F,d0
bne RPORT.BP
addq.l #8,a3
rts
; --------------------------------------------------------------
; Fetch one Word
FETCH_W:
movem.l a2,-(a7)
move.w CA.GTINT,a2
bsr GET_ONE
bne.s FETCH_WX
move.l a1,BV_RIP(a6)
moveq #0,d1
move.w 0(a6,a1.l),d1
addq.l #2,BV_RIP(a6)
FETCH_WX:
movem.l (a7)+,a2
tst.l d0
rts
; --------------------------------------------------------------
; Fetch one long word
FETCH_L:
movem.l a2,-(a7)
move.w CA.GTLIN,a2
bsr.s GET_ONE
bne.s FETCH_LX
move.l a1,BV_RIP(a6)
move.l 0(a6,a1.l),d1
addq.l #4,BV_RIP(a6)
FETCH_LX:
movem.l (a7)+,a2
tst.l d0
rts
; --------------------------------------------------------------
; Fetch one floating point number
FETCH_F:
movem.l a2,-(a7)
move.w CA.GTFP,a2
bsr.s GET_ONE
bne.s FETCH_FX
move.l a1,BV_RIP(a6)
move.w 0(a6,a1.l),d1
move.l 2(a6,a1.l),d2
addq.l #6,BV_RIP(a6)
FETCH_FX:
movem.l (a7)+,a2
tst.l d0
rts
; --------------------------------------------------------------
; Fetch one string
FETCH_S:
movem.l a2,-(a7)
move.w CA.GTSTR,a2
bsr.s GET_ONE
bne.s FETCH_SX
move.l a1,BV_RIP(a6)
moveq #3,d1 ; get total length of string
add.w 0(a6,a1.l),d1
bclr #0,d1
add.l d1,BV_RIP(a6) ; and reset ri stack pointer
FETCH_SX:
movem.l (a7)+,a2
tst.l d0
rts
; --------------------------------------------------------------
; This routine gets one parameter and returns it on the maths
; stack, pointed to by (A1).
;
; Entry: A2.L routine to call (i.e. CA.GTINT)
; A3.L pointer to first parameter
; A5.L pointer to last parameter
;
; Exit: A3.L updated
; A5.L updated
; A1.L updated pointer to top of maths stack
; D0.L error code
;
GET_ONE:
movem.l d1-d6/a0/a2,-(a7)
lea 8(a3),a0
cmp.l a0,a5
blt.s GET_ONEBp
move.l BV_RIP(a6),a1
move.l a5,-(a7)
move.l a0,a5
move.l a5,-(a7)
jsr (a2)
movem.l (a7)+,a0/a5
tst.l d0
bne.s GET_ONEX
move.l a0,a3
move.l a1,BV_RIP(a6)
bra.s GET_ONEX
GET_ONEBp:
moveq #ERR.BP,d0
GET_ONEX:
movem.l (a7)+,d1-d6/a0/a2
tst.l d0
rts
; --------------------------------------------------------------
; Get a filename on the stack
;
; Entry: A3.L pointer to first parameter
; A5.L pointer to last parameter
;
; Exit: A3.L updated
; A5.L updated
; D0.L...error code
; A1.L pointer to string on math stack
GET1_FNAMES:
movem.l d1/d4/d6/a2,-(a7)
cmp.l a3,a5
beq GET1_BP
move.l BV_RIP(a6),a1
tst.w 2(a6,a3.l) ; Test for parameter name
bmi.s GET1_STR ; none? ...must be exprssn.
moveq #$0f,d0 ; extract type of parameter.
and.b 1(a6,a3.l),d0
subq.b #1,d0 ; is it a string?
bne.s GET1_NAM ; no, use name instead
GET1_STR:
move.l a5,-(sp) ; save the top pointer
lea 8(a3),a5 ; get just one string
move.w CA.GTSTR,a2
jsr (a2)
move.l (sp)+,a5 ; restore top pointer
tst.l d0
bne.s GET1_RTS
move.l a1,BV_RIP(a6)
moveq #3,d1 ; get total length of string
add.w 0(a6,a1.l),d1
bclr #0,d1
add.l d1,BV_RIP(a6) ; and reset ri stack pointer
bra.s GET1_OK
GET1_NAM:
moveq #0,d1
move.w 2(a6,a3.l),d1 ; pointer to real entry
bmi.s GET1_BP ; ... expression is no good
lsl.l #3,d1 ; in multiples of 8 bytes
add.l BV_NTBAS(a6),d1
moveq #0,d6
move.w 2(a6,d1.l),d6 ; pointer to the name
add.l BV_NLBAS(a6),d6
moveq #0,d1 ; get the length of the name
move.b 0(a6,d6.l),d1 ; as a long word.
addq.l #1,d1 ; rounded up
bclr #0,d1
move.w d1,d4 ; and save it
addq.l #2,d1 ; space required is +2 bytes
move.w BV.CHRIX,a2 ; on ri stack
jsr (a2)
move.l BV_RIP(a6),a1
add.w d4,d6 ; move to end of string
GET1_NMLUP:
subq.l #1,a1 ; copy one byte at a time
move.b 0(a6,d6.l),0(a6,a1.l)
subq.l #1,d6
dbra d4,GET1_NMLUP ; including the (byte) name
* length
subq.l #1,a1 ; put a zero on to make it a
clr.b 0(a6,a1.l) ; word
GET1_OK:
lea 8(a3),a3 ; update parameter pointer
moveq #ERR.OK,d0
bra.s GET1_RTS
GET1_BP:
moveq #ERR.BP,d0
GET1_RTS:
tst.l d0
movem.l (a7)+,d1/d4/d6/a2
rts
; --------------------------------------------------------------
; Get channel parameter
; Entry: A3.L pointer to first parameter
; A5.L pointer to last parameter
; D1.L default channel #
;
; Exit: A0.L CH.ID (default d1)
; A2.L CH.BASE
; A3.L updated
; A5.L updated
; D0.L error code
;
FETCH_CH:
movem.l d1/d3/a1,-(a7)
move.l BV_RIP(a6),a1
cmp.l a3,a5
beq.s FETCH_CH1
btst #7,1(a6,a3.l)
beq.s FETCH_CH1
bsr FETCH_W
bne.s FETCH_CHX
FETCH_CH1:
mulu #$28,d1
add.l BV_CHBAS(a6),d1
cmp.l BV_CHP(a6),d1
bge.s FETCH_CHNO
move.l d1,a2
move.l 0(a6,a2.l),a0
move.w a0,d1
bmi.s FETCH_CHNO
moveq #ERR.OK,d0
bra.s FETCH_CHX
FETCH_CHNO:
moveq #ERR.NO,d0
FETCH_CHX:
movem.l (a7)+,d1/d3/a1
rts
; -------------------------------------------------------------
; Get a job ID
;
; Entry: a3.L pointer to first parameter
; a5.L pointer to last parameter
;
; Exit: d1.l JOB ID
; a3.L updated
; a5.L updated
; d0.L error code
FETCH_ID:
movem.l d2/d5,-(a7)
move.l a5,d5
sub.l a3,d5
beq.s ID_BP
subq.w #8,d5
bne.s ID_1
bsr FETCH_L ; JOB ID
bra.s ID_X
ID_1:
subq.w #8,d5
bne.s ID_BP
bsr.s COMMA
bne.s ID_BP
bsr FETCH_W ; JOB No
bne.s ID_X
move.w d1,d2
swap d2
bsr FETCH_W ; JOB tag
bne.s ID_X
move.w d1,d2
move.l d2,d1
moveq #ERR.OK,d0
bra.s ID_X
ID_BP:
moveq #ERR.BP,d0
ID_X:
movem.l (a7)+,d2/d5
rts
; -------------------------------------------------------------
COMMA:
move.b 1(a6,a3.l),d0
and.w #$70,d0
cmpi.b #$10,d0 ; ','
rts
BKSLSH:
move.b 1(a6,a3.l),d0
and.w #$70,d0
cmpi.b #$30,d0 ; '\'
rts
; -------------------------------------------------------------
; Return true or false back to BASIC
RET_FLS:
moveq #0,d1
bra.s RET_W
RET_TRU:
moveq #1,d1
; --------------------------------------------------------------
; Return word d1.w to BASIC
RET_W:
move.l d1,d4
moveq.l #2,d1
move.w BV.CHRIX,a2
jsr (a2)
move.l d4,d1
move.l BV_RIP(a6),a1 ; Get arith stack pointer
subq.l #2,a1 ; room for 2 bytes
move.l a1,BV_RIP(a6)
move.w d1,0(a6,a1.l) ; Put int number on stack
moveq.l #3,d4 ; set Integer type
moveq.l #ERR.OK,d0 ; no errors
rts
; -------------------------------------------------------------
; Return long Integer d1.l to BASIC
RET_L:
move.l d1,d4
moveq.l #6,d1
move.w BV.CHRIX,a2
jsr (a2)
move.l d4,d1
bsr.s CONV_L2F
subq.l #6,BV_RIP(a6)
move.l BV_RIP(a6),a1
move.w d2,0(a6,a1.l)
move.l d1,2(a6,a1.l)
moveq.l #2,d4
moveq.l #ERR.OK,d0
rts
; -------------------------------------------------------------
; convert long Integer to floating point form.
; Entry: d1.l = long int
; Exit: d1.w = mantissa
; d2.l = exponent
CONV_L2F:
move.l d1,d2
beq.s CONV_L2FX
move.w #$81F,d2
move.l d1,-(a7)
CONV_L2F1:
add.l d1,d1
bvs.s CONV_L2F2
subq.w #1,d2
move.l d1,(a7)
bra.s CONV_L2F1
CONV_L2F2:
move.l (a7)+,d1
CONV_L2FX:
rts
; -------------------------------------------------------------
; Return 4 character string d1.l to BASIC
RET_4S:
move.l d1,d4
moveq.l #6,d1
move.w BV.CHRIX,a2
jsr (a2)
move.l d4,d1
subq.l #6,BV_RIP(a6)
move.l BV_RIP(a6),a1
move.w #4,0(a6,a1.l)
move.l d1,2(a6,a1.l)
moveq #1,d4
moveq #ERR.OK,d0
rts
; -------------------------------------------------------------
; print string at (a1) to channel with id a0
IOSTRG:
movem.l d1-d3/a1-a2,-(a7)
move.w UT.MTEXT,a2
jsr (a2)
movem.l (a7)+,d1-d3/a1-a2
rts
; --------------------------------------------------------------
RPORT.OR moveq #ERR.OR,d0
rts
RPORT.NO moveq #ERR.NO,d0
rts
RPORT.BP moveq #ERR.BP,d0
rts
; --------------------------------------------------------------
END